import {
  ArgumentsHost,
  Catch,
  ExceptionFilter,
  HttpException,
  HttpStatus,
} from '@nestjs/common';
import { Logger } from 'src/common/logger/logger';

/**
 * 全局接口异常过滤器
 * 用于处理全局接口异常，返回统一的错误格式
 * throw new HttpException('用户已存在', 401);
 */
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  constructor(private readonly logger: Logger) {}

  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp(); // 获取请求上下文
    const response = ctx.getResponse(); // 获取请求上下文中的 response对象
    const status = exception.getStatus(); // 获取异常状态码
    const request = ctx.getRequest();
    const exceptionResponse: any = exception.getResponse();

    let validMessage = ''; // 存储异常信息
    if (
      Object.prototype.toString.call(exceptionResponse) === '[object Object]' &&
      Object.prototype.hasOwnProperty.call(exceptionResponse, 'message')
    ) {
      validMessage =
        typeof exceptionResponse.message === 'string'
          ? exceptionResponse.message
          : exceptionResponse.message[0];
    }

    // 设置错误信息
    const message = exception.message
      ? exception.message
      : `${status >= HttpStatus.INTERNAL_SERVER_ERROR ? 'Service Error' : 'Client Error'}`;

    const logFormat = `
#############################################
Request original url: ${request.originalUrl}
Method: ${request.method}
IP: ${request.ip}
User agent: ${request.headers['user-agent']}
Status code: ${status}
Params: ${JSON.stringify(request.params)}
Query: ${JSON.stringify(request.query)}
Body: ${JSON.stringify(request.body)}
Response: ${exception.toString() + `（${validMessage || message}）`}
#############################################
`;
    this.logger.error('HttpException filter ', logFormat);

    // 设置返回的状态码， 请求头，发送错误信息
    response.status(status).json({
      data: {},
      retcode: -1,
      message: validMessage || message,
    });
  }
}
